package cn.eeepay.framework.service.profitActivityRecord.impl;

import cn.eeepay.framework.dao.AgentInfoDao;
import cn.eeepay.framework.dao.AgentProfitActivityUpdateRecord.AgentProfitActivityUpdateRecordDao;
import cn.eeepay.framework.dao.AgentShareDao;
import cn.eeepay.framework.model.*;
import cn.eeepay.framework.service.profitActivityRecord.AgentProfitActivityUpdateRecordService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;

@Service
@Transactional
public class AgentProfitActivityUpdateRecordServiceImpl implements AgentProfitActivityUpdateRecordService {
    private static final Logger log = LoggerFactory.getLogger(AgentProfitActivityUpdateRecordServiceImpl.class);
    @Autowired
    private AgentProfitActivityUpdateRecordDao agentProfitActivityUpdateRecordDao;
    @Autowired
    private AgentShareDao agentShareDao;
    @Autowired
    private AgentInfoDao agentInfoDao;

    private static final String[] profitArr = new String[]{
            "costRateType","perFixCost","costRate",
            "profitType","shareProfitPercent",
            "ladder1Rate","ladder1Max",
            "ladder2Rate","ladder2Max",
            "ladder3Rate","ladder3Max",
            "ladder4Rate","ladder4Max"
    };

    private static final String[] happyBackArr = new String[]{
            "taxRate","repeatRegisterRatio","rewardRate","rewardRateRepeat"
    };

    private static Map<String,String> happyBackText = new HashMap<String,String>(); 
    
    {
        happyBackText.put("taxRate","首次注册返现比例");
        happyBackText.put("rewardRate","首次注册奖励比例");
        happyBackText.put("repeatRegisterRatio","重复注册返现比例");
        happyBackText.put("rewardRateRepeat","重复注册奖励比例");
    }


    @Override
    public int insertMainRecord(AgentProfitActivityUpdateRecord apau) {
        return agentProfitActivityUpdateRecordDao.insertMainRecord(apau);
    }
    @Override
    public int insertRecorDetail(String text, Long id, String username) {
        return agentProfitActivityUpdateRecordDao.insertRecorDetail(text,id,username);
    }
    @Override
    public void compareShareProfit(AgentShareRuleTask share) {
        AgentShareRule oldAsr = agentShareDao.getAgentShareRuleById(share.getShareId());
        AgentShareRule newAsr = new AgentShareRule();
        BeanUtils.copyProperties(share,newAsr);
        compareShare(oldAsr,newAsr,profitArr,null);
    }
    @Override
    public void compareHappyBackRecord(String agentNo, List<ActivityHardwareType> happyBackTypes,String subType) {
        if(happyBackTypes!=null && happyBackTypes.size()>0){
            //查询出旧的欢乐返集合
            List<ActivityHardwareType> oldList = agentInfoDao.selectHappyBackByAgentNoSubType(agentNo,subType);
            Map<String,ActivityHardwareType> activityTypeNoMap = new HashMap<>();
            for (ActivityHardwareType aht: oldList) {
                activityTypeNoMap.put(aht.getActivityTypeNo(),aht);
            }
            //根据当前的happy
            List<String> textList = new ArrayList<>();
            for (ActivityHardwareType aht:happyBackTypes) {
                ActivityHardwareType old = activityTypeNoMap.get(aht.getActivityTypeNo());
                if(old==null){
                    StringBuffer sb = new StringBuffer();
                    sb.append("新增").append(aht.getActivityTypeName());
                    if("1".equals(subType)){
                        sb.append(" 欢乐返设置,[欢乐返子类型编号");
                    }else{
                        sb.append(" 新欢乐送活动设置,[新欢乐送子类型编号");
                    }
                    sb.append(aht.getActivityTypeNo()).append("]");
      /*              sb.append(happyBackText.get("taxRate")).append(" ").append("改为").append(getHappyShowRate(aht.getTaxRate())).append(",");
                    sb.append(happyBackText.get("repeatRegisterRatio")).append(" ").append("改为").append(getHappyShowRate(aht.getRepeatRegisterRatio())).append(",");
                    sb.append(happyBackText.get("rewardRate")).append(" ").append("改为").append(getHappyShowRate(aht.getRewardRate())).append(",");
                    sb.append(happyBackText.get("rewardRateRepeat")).append(" ").append("改为").append(getHappyShowRate(aht.getRewardRateRepeat()));*/
                    textList.add(sb.toString());
                }else{
                    Map<String, List<Object>> stringListMap = compareFields(old, aht, happyBackArr, null);
                    if(stringListMap.size()>0){
                        StringBuffer sb = new StringBuffer();
                        sb.append("修改").append(aht.getActivityTypeName());
                        if("1".equals(subType)){
                            sb.append(" 欢乐返设置,[欢乐返子类型编号");
                        }else{
                            sb.append(" 新欢乐送活动设置,[新欢乐送子类型编号");
                        }
                        sb.append(aht.getActivityTypeNo()).append("]的");

                        //数据库只存储两位,进位,判断进位后是否一致
                        boolean hasDif = false;
                        for(Map.Entry<String, List<Object>> entry : stringListMap.entrySet()){
                            String key = happyBackText.get(entry.getKey());
                            List<Object> value = entry.getValue();
                            if(key!=null){
                                String oldValue = getHappyShowRate(new BigDecimal(value.get(0).toString()));
                                String newValue = getHappyShowRate(new BigDecimal(value.get(1).toString()));
                                if(!oldValue.equals(newValue)){
                                    hasDif = true;
                                    sb.append(key).append(oldValue).append("改为").append(newValue).append(",");
                                }

                            }
                        }
                        String s = sb.toString();
                        if(hasDif){
                            textList.add(s.substring(0,s.length() - 1));
                        }
                    }
                }
            }
            if(textList.size()>0){
                AgentProfitActivityUpdateRecord apau = getAgentProfitActivityUpdateRecord(agentNo,null,(Integer.valueOf(subType)+1)+"");
                agentProfitActivityUpdateRecordDao.insertMainRecord(apau);

                List<AgentProfitActivityUpdateDetail> list = new ArrayList<>();
                for (String text:textList) {
                    AgentProfitActivityUpdateDetail  detail = new AgentProfitActivityUpdateDetail();
                    detail.setDetail(text);
                    detail.setRecordId(apau.getId());
                    detail.setCreatePerson(apau.getCreatePerson());
                    list.add(detail);
                }
                agentProfitActivityUpdateRecordDao.insertRecorDetailBatch(list);
            }
        }
    }

    private String getHappyShowRate(BigDecimal bigDecimal){
        if(bigDecimal==null){
            return "";
        }
        return bigDecimal.setScale(2,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)).intValue() + "%";
    }

    /**
     *
     * @param agentNo
     * @param operEntry  1-分润设置 2-欢乐返活动 3-新欢乐送活动'
     * @return
     */
    private AgentProfitActivityUpdateRecord getAgentProfitActivityUpdateRecord(String agentNo,String parentId,String operEntry){
        final UserLoginInfo principal = (UserLoginInfo) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        AgentProfitActivityUpdateRecord apau = new AgentProfitActivityUpdateRecord();
        //插入主表
        apau.setAgentNo(agentNo);
        apau.setParentId(parentId);
        apau.setEffectTime(new Date());
        //获取当前登录
        apau.setOperEntry(operEntry);//1-分润设置 2-欢乐返活动 3-新欢乐送活动'
        apau.setCreatePerson(principal.getUsername());
        return apau;
    }


    private void compareShare(Object oldObj, Object newObj,String[] onlyCheckArr,String[] ignoreArr){
        Map<String, List<Object>> difMap = this.compareFields(oldObj, newObj,onlyCheckArr,ignoreArr);
        log.info("对比差异===================================>:"+difMap.toString());
        if(difMap.size()>0){
            AgentShareRule oldAsr = (AgentShareRule)oldObj;
            AgentShareRule newAsr = (AgentShareRule)newObj;

            AgentProfitActivityUpdateRecord apau = getAgentProfitActivityUpdateRecord(oldAsr.getAgentNo(),null,"1");;
            agentProfitActivityUpdateRecordDao.insertMainRecord(apau);

            //遍历map 插入详情表
            StringBuffer sb = new StringBuffer();
            sb.append("修改[业务产品名称:").append(oldAsr.getBpName()).append(",")
                    .append("服务名称:").append(oldAsr.getServiceName()).append(",")
                    .append("银行卡种类:").append(oldAsr.getCardName()).append("]")
                    .append("代理商成本");
            sb.append(getCostRateType(oldAsr)).append("改为:").append(getCostRateType(newAsr)).append("、");
            sb.append(getProfitTypeText(oldAsr)).append("修改为:").append(getProfitTypeText(newAsr));
            agentProfitActivityUpdateRecordDao.insertRecorDetail(sb.toString(),apau.getId(),apau.getCreatePerson());
        }
    }

    private String getCostRateType(AgentShareRule asr){
        if(asr.getCostRateType().equals("1")){
            return asr.getPerFixCost()+"元";
        }else {
            return setBigDecimalScale(asr.getCostRate())+"%";
        }
    }



    private String getProfitTypeText(AgentShareRule asr){
        if(5==asr.getProfitType()){
            if(asr.getShareProfitPercent()!=null){
                return "代理商固定分润百分比:" + setBigDecimalScale(asr.getShareProfitPercent()) + "%";
            }
        }else if(6==asr.getProfitType()){
            return "代理商阶梯分润百分比:" +
                    setBigDecimalScale(asr.getLadder1Rate()) + "%<" + setMoney(asr.getLadder1Max()) + "<"+
                    setBigDecimalScale(asr.getLadder2Rate()) + "%<" + setMoney(asr.getLadder2Max()) + "<"+
                    setBigDecimalScale(asr.getLadder3Rate()) + "%<" + setMoney(asr.getLadder3Max()) + "<"+
                    setBigDecimalScale(asr.getLadder4Rate()) + "%<" + setMoney(asr.getLadder4Max());
        }
        return "";
    }

    private static String setMoney(BigDecimal bigDecimal){
        if(bigDecimal==null){
            return " ";
        }
        return bigDecimal.multiply(new BigDecimal(10000).setScale(0)).toString() + "元";
    }
    private static String setBigDecimalScale(BigDecimal bigDecimal){
        if(bigDecimal==null){
            return " ";
        }
         bigDecimal = bigDecimal.setScale(4, BigDecimal.ROUND_DOWN);
        DecimalFormat df = new DecimalFormat("#.0000");
        if(bigDecimal.compareTo(BigDecimal.ZERO)==0) {
            return "0.0000";
        }else if(bigDecimal.compareTo(BigDecimal.ZERO)>0&&bigDecimal.compareTo(new BigDecimal(1))<0){
            return "0"+df.format(bigDecimal).toString();
        }else if(bigDecimal.compareTo(BigDecimal.ZERO)<0&&bigDecimal.compareTo(new BigDecimal(-1))>0){
            df = new DecimalFormat("0.0000");
            return df.format(bigDecimal);
        }else {
            return df.format(bigDecimal).toString();
        }
    }
    public Map<String, List<Object>> compareFields(Object oldObj, Object newObj,String[] onlyCheckArr,String[] ignoreArr) {
        try{
            Map<String, List<Object>> map = new HashMap<String, List<Object>>();

            List<String> ignoreList = null;
            List<String> onlyCheckList = null;

            if(ignoreArr != null && ignoreArr.length > 0){
                ignoreList = Arrays.asList(ignoreArr);
            }
            if(onlyCheckArr != null && onlyCheckArr.length > 0){
                onlyCheckList = Arrays.asList(onlyCheckArr);
            }
            //如果旧的为空则认为全追加,如果新的为空,则认为没变化
            if(oldObj==null || newObj==null){
                return map;
            }

            if (oldObj.getClass() == newObj.getClass()) {// 只有两个对象都是同一类型的才有可比性
                Class clazz = oldObj.getClass();
                // 获取object的属性描述
                PropertyDescriptor[] pds = Introspector.getBeanInfo(clazz,
                        Object.class).getPropertyDescriptors();
                for (PropertyDescriptor pd : pds) {// 这里就是所有的属性了
                    String name = pd.getName();// 属性名
                    if(ignoreList != null && ignoreList.contains(name)){// 如果当前属性选择忽略比较，跳到下一次循环
                        continue;
                    }
                    if(onlyCheckList != null && !onlyCheckList.contains(name)){// 如果当前属性选择不是
                        continue;
                    }
                    Method readMethod = pd.getReadMethod();// get方法
                    // 在obj1上调用get方法等同于获得obj1的属性值
                    Object o1 = readMethod.invoke(oldObj);
                    // 在obj2上调用get方法等同于获得obj2的属性值
                    Object o2 = readMethod.invoke(newObj);

                    if(o1 == null && o2 == null){
                        continue;
                    }else if(o1 == null && o2 != null || o1 != null && o2 == null){
                        List<Object> list = new ArrayList<Object>();
                        list.add(o1);
                        list.add(o2);
                        map.put(name, list);
                        continue;
                    }

                    if(o1 instanceof BigDecimal && o2 instanceof BigDecimal){
                        if(((BigDecimal)o1).compareTo((BigDecimal)o2)==0){
                            continue;
                        }
                    }

                    if (!o1.equals(o2)) {// 比较这两个值是否相等,不等就可以放入map了
                        List<Object> list = new ArrayList<Object>();
                        list.add(o1);
                        list.add(o2);
                        map.put(name, list);
                    }
                }
            }
            return map;
        }catch(Exception e){
            e.printStackTrace();
            return new HashMap<>();
        }
    }
}
